package com.oriental.manage.controller.opcif;

import com.oriental.manage.core.excelUtils.ExcelTemplateUtil;
import com.oriental.manage.core.fileUtils.ExcelContentExt;
import com.oriental.manage.core.fileUtils.FileDownAjax;
import com.oriental.manage.core.fileUtils.HeaderExt;
import com.oriental.manage.core.paging.Pagination;
import com.oriental.manage.core.response.ResponseDTO;
import com.oriental.manage.core.system.Constants;
import com.oriental.manage.core.system.log.OperateLogger;
import com.oriental.manage.core.utils.Bean2MapUtil;
import com.oriental.manage.core.utils.DateUtils;
import com.oriental.manage.pojo.payCount.BoundRateReqModel;
import com.oriental.opcif.common.model.RequestModel;
import com.oriental.opcif.common.model.ResponseModel;
import com.oriental.opcif.product.bizModel.request.boundCount.BoundRateReqDto;
import com.oriental.opcif.product.bizModel.response.boudCount.BoundRateResDto;
import com.oriental.opcif.product.facade.bankCount.BankCountFacade;
import com.oriental.paycenter.commons.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.webbuilder.office.excel.config.ExcelWriterConfig;
import org.webbuilder.office.excel.config.Header;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by Chuch on 2017/5/3
 */
@Slf4j
@Controller
@RequestMapping("cif/agreementRateReport")
public class AgreementRateReportController {
    public static final long DEFAULT_DAY = 92;

    @Autowired(required = false)
    private BankCountFacade bankCountFacade;


    @Autowired
    private Constants constants;
    @Autowired
    private FileDownAjax fileDownAjax;

    @RequestMapping("init")
    @RequiresPermissions("agreementRateReport_search")
    public String init() {
        return "payCount/searchAgreementRateReport";
    }

    @RequestMapping("/search")
    @ResponseBody
    @RequiresPermissions("agreementRateReport_search")
    @OperateLogger(content = "绑卡报表查询", operationType = OperateLogger.OperationType.R)
    public ResponseDTO<Pagination<BoundRateResDto>> queryPage(@RequestBody Pagination<BoundRateReqDto> query) {
        log.info("绑卡报表查询数据", query);
        ResponseDTO<Pagination<BoundRateResDto>> responseDTO = new ResponseDTO<>();
        try {
            if (query.getQueryBean() == null) {
                log.error("交易参数不能为空");
                responseDTO.setSuccess(false);
                responseDTO.setMsg("交易参数不能为空");
                return responseDTO;
            }
            if (query.getQueryBean().getStartTime() == null || query.getQueryBean().getEndTime() == null) {
                query.getQueryBean().setEndTime(DateUtil.getCurrent(DateUtil.datePattern));
                query.getQueryBean().setStartTime(DateUtil.format(new Date(System.currentTimeMillis() - DEFAULT_DAY * 24 * 3600 * 1000), DateUtil.datePattern));
            } else {
                long endTime = DateUtil.parse(query.getQueryBean().getEndTime(), DateUtil.datePattern).getTime();
                long startTime = DateUtil.parse(query.getQueryBean().getStartTime(), DateUtil.datePattern).getTime();
                if (endTime > startTime + DEFAULT_DAY * 24 * 3600 * 1000) {
                    log.error("交易统计查询失败，查询时间大于{}", DEFAULT_DAY);
                    responseDTO.setSuccess(false);
                    responseDTO.setMsg("查询时间不能大于" + DEFAULT_DAY + "天");
                    return responseDTO;
                }
            }
            RequestModel<BoundRateReqDto> requestModel = new RequestModel<BoundRateReqDto>();
            requestModel.setPageNo(query.getPageNum());
            requestModel.setPageSize(query.getPageSize());

            query.getQueryBean().setBankName(CountMap.getBankName(query.getQueryBean().getBankName()));
            requestModel.setRequest(query.getQueryBean());

            Pagination<BoundRateResDto> pagination = new Pagination<>();
            pagination.setPageNum(query.getPageNum());
            pagination.setPageSize(query.getPageSize());

            ResponseModel<BoundRateResDto> responseModel1 = bankCountFacade.queryBoundRate(requestModel);
            if (responseModel1.getResponseResult()) {
                pagination.setRowCount(responseModel1.getTotal());
                pagination.setList(responseModel1.getList());
                responseDTO.setSuccess(true);
                responseDTO.setObject(pagination);
                log.info("查询结果:{}", responseModel1);
            } else {
                responseDTO.setSuccess(false);
                responseDTO.setMsg(responseModel1.getResponseMessage());
            }
        } catch (Exception e) {
            log.error("查询失败", e);
            responseDTO.setSuccess(false);
            responseDTO.setMsg(e.getMessage());
        }
        return responseDTO;
    }


    @RequiresPermissions("refund-report_download")
    @RequestMapping("/download")
    public ResponseEntity<byte[]> download(@RequestBody BoundRateReqModel query) {
        ResponseEntity<byte[]> responseEntity;
        File tempFile = null;
        try {
            InputStream inputStream = new FileInputStream(constants.getExcelPath() + "/绑卡报表.xlsx");
            tempFile = fileDownAjax.touch("绑卡报表" + DateUtils.now() + ".xlsx");

            RequestModel<BoundRateReqDto> requestModel = new RequestModel<BoundRateReqDto>();
            BoundRateReqDto boundRateReqDto = new BoundRateReqDto();
            boundRateReqDto.setStartTime(DateUtil.format(query.getStartTime(), DateUtil.datePattern));
            boundRateReqDto.setEndTime(DateUtil.format(query.getEndTime(), DateUtil.datePattern));
            boundRateReqDto.setBankName(CountMap.getBankName(query.getBankName()));
            requestModel.setPageNo(1);
            requestModel.setPageSize(10000);
            requestModel.setRequest(boundRateReqDto);
            ResponseModel<BoundRateResDto> responseModel1 = bankCountFacade.queryBoundRate(requestModel);
            //表头
            LinkedList<Header> tHeaders = new LinkedList<>();
            //内容
            List<Object> datas = new ArrayList<>();
            //添加表头
            tHeaders.add(new HeaderExt("序号", "index"));
            tHeaders.add(new HeaderExt("支付机构", "orgCode", ExcelContentExt.ORGANIZE));
            tHeaders.add(new HeaderExt("银行名称", "bankName", ExcelContentExt.BANK_INFO));
            tHeaders.add(new HeaderExt("账号类型", "cardType"));
            tHeaders.add(new HeaderExt("申请开始日期", "startTime"));
            tHeaders.add(new HeaderExt("申请结束日期", "endTime"));
            tHeaders.add(new HeaderExt("总申请数", "applyTotal"));
            tHeaders.add(new HeaderExt("申请成功", "applySuccessTotal"));
            tHeaders.add(new HeaderExt("申请失败", "applyFailTotal"));
            tHeaders.add(new HeaderExt("成功占比", "applySuccessRate"));
            tHeaders.add(new HeaderExt("失败占比", "applyFailRate"));
            tHeaders.add(new HeaderExt("签约总数", "boundTotal"));
            tHeaders.add(new HeaderExt("签约成功", "boundSuccessTotal"));
            tHeaders.add(new HeaderExt("签约失败", "boundFailTotal"));
            tHeaders.add(new HeaderExt("成功占比", "boundSuccessRate"));
            tHeaders.add(new HeaderExt("失败占比", "boundFailRate"));

            if (responseModel1.getResponseResult() && responseModel1.getList().size() > 0) {
                int i = 1;
                int applyTotal = 0;
                int applySuccessTotal = 0;
                int applyFailTotal = 0;
                String applySuccessRate = "";
                String applyFailRate = "";
                int boundTotal = 0;
                int boundSuccessTotal = 0;
                int boundFailTotal = 0;
                String boundSuccessRate = "";
                String boundFailRate = "";
                for (BoundRateResDto agreementReportDto : responseModel1.getList()) {
                    if (agreementReportDto.getOrgCode() == null) {
                        agreementReportDto.setOrgCode("未知");
                    }
                    if (agreementReportDto.getCardType() != null) {
                        if (agreementReportDto.getCardType().equals("DB")) {
                            agreementReportDto.setCardType("借记卡");
                        } else if (agreementReportDto.getCardType().equals("CD")) {
                            agreementReportDto.setCardType("贷记卡");
                        }
                    }
                    Map map = Bean2MapUtil.convertBean(agreementReportDto);
                    applyTotal += agreementReportDto.getApplyTotal();
                    applySuccessTotal += agreementReportDto.getApplySuccessTotal();
                    applyFailTotal += agreementReportDto.getApplyFailTotal();
                    applySuccessRate = division(applySuccessTotal, applyTotal);
                    applyFailRate = division(applyFailTotal, applyTotal);
                    boundTotal += agreementReportDto.getBoundTotal();
                    boundSuccessTotal += agreementReportDto.getBoundSuccessTotal();
                    boundFailTotal += agreementReportDto.getBoundFailTotal();
                    boundSuccessRate = division(boundSuccessTotal, boundTotal);
                    boundFailRate = division(boundFailTotal, boundTotal);
                    map.put("index", i);
                    i++;
                    datas.add(map);
                }

                //增加一行合计
                Map map = Bean2MapUtil.convertBean(BoundRateResDto.class);
                map.put("endTime", "合计");
                map.put("applyTotal", applyTotal);
                map.put("applySuccessTotal", applySuccessTotal);
                map.put("applyFailTotal", applyFailTotal);
                map.put("applySuccessRate", applySuccessRate);
                map.put("applyFailRate", applyFailRate);
                map.put("boundTotal", boundTotal);
                map.put("boundSuccessTotal", boundSuccessTotal);
                map.put("boundFailTotal", boundFailTotal);
                map.put("boundSuccessRate", boundSuccessRate);
                map.put("boundFailRate", boundFailRate);
                datas.add(map);
            }

            ExcelWriterConfig config = new ExcelWriterConfig();
            config.setHeaders(tHeaders);
            config.setDatas(datas);
            config.setStartWith(4);
            FileOutputStream outputStream = new FileOutputStream(tempFile);
            ExcelTemplateUtil.write(inputStream, outputStream, config);
            responseEntity = fileDownAjax.getResponseEntity(tempFile);
        } catch (Exception e) {
            log.error("下载失败", e);
            responseEntity = fileDownAjax.getResponseEntityFail();
        } finally {
            fileDownAjax.forceDelete(tempFile);
        }
        return responseEntity;
    }


    private static String division(int a, int b) {
        DecimalFormat df = new DecimalFormat("0.00");
        return df.format((float) (a * 100) / b)+"%";
    }
}
